home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 4_0 / STANDALO / RESMAP-F / RESMAP_F.C next >
C/C++ Source or Header  |  1991-01-27  |  8KB  |  340 lines

  1. /*
  2.     ResMap FKEY  by James W. Walker
  3.  
  4.     This FKEY displays a list of the open resource files,
  5.     in the order in which the Resource Manager searches them.
  6.     
  7.     This is written for THINK C 4.0.  Note that "Custom Headers"
  8.     should be turn on in the "Set Project Type..." dialog.
  9.  
  10. */
  11.  
  12. #define    DEBUGGING    0    /* Compile in DebugStr instructions? */
  13.  
  14. #if    DEBUGGING
  15. #define DEBUGSTR(s)        DebugStr(s)
  16. #else
  17. #define DEBUGSTR(s)        SysBeep(1)
  18. #endif
  19.  
  20. #include <HFS.h>
  21. #include <FileMgr.h>
  22. #include <MultiFinder.h>
  23. #include <MacProto.h>
  24.  
  25. #define        nil        0L
  26. #define MOVE_TO_FRONT        -1L
  27.  
  28. #define    BUTTON_WIDTH        60
  29. #define BUTTON_HEIGHT        20
  30. #define    BUTTON_GAP            10        /* Vertical distance from button */
  31.                                     /* to other stuff. */
  32.  
  33. #define    BOX_HEIGHT            250
  34. #define BOX_WIDTH            240
  35.  
  36. #define OSDISPATCH        0xA88F
  37. #define UNIMPLEMENTED    0xA89F
  38.  
  39. typedef struct Resource_map {
  40.     long                    rhead[4];
  41.     struct Resource_map        **next;    /* Handle to next resource map. */
  42.     short                    refnum;    /* resource file reference number */
  43.     /* ...and other stuff I don't need to reference. */
  44. } **ResMap_h;
  45.  
  46. typedef struct QuickDraw {
  47.     long    randSeed;
  48.     BitMap    screenBits;
  49.     Cursor    arrow;
  50.     Pattern    dkGray;
  51.     Pattern    ltgray;
  52.     Pattern    gray;
  53.     Pattern    black;
  54.     Pattern    white;
  55.     GrafPtr    thePort;
  56. } QuickDraw;
  57.  
  58. /* --------------- Prototypes --------------------- */
  59. Boolean        Check_handle( Handle h, Ptr top_mem );
  60. void        main( void );
  61.  
  62.  
  63. /* ------------------- main ----------------------- */
  64. void main()
  65. {
  66.     register WindowPtr    my_window;
  67.     WindowPtr    which_window;
  68.     Rect        bounds, listview, databounds, listbox, button_rect;
  69.     GrafPtr        save_port;
  70.     register ResMap_h    this_map;
  71.     FCBPBRec    fcb;
  72.     Str255        filename;
  73.     ListHandle    list;
  74.     Cell        ncell;    /*  name */
  75.     EventRecord    event;
  76.     Boolean        done;
  77.     short            place, part;
  78.     ControlHandle    button, which_control;
  79.     int            cur_resfile    = CurResFile();
  80.     register short    row_num;
  81.     Ptr            top_mem;
  82.     QuickDraw    *QD_globals;
  83.     static Boolean        running = false;    /* Prevent reentrance */
  84.     
  85.     asm {
  86.         movem.l    a0-a5/d0-d7, -(SP)    ; save registers
  87.         LEA        main, A4            ; for addressing the static variable
  88.     }
  89.     if (running)
  90.     {
  91.         SysBeep(1);
  92.         goto reentrant_exit;
  93.     }
  94.     running = true;
  95.     GetPort( &save_port );
  96.     
  97.     /* Find the top of RAM, for checking handles. */
  98.     if (NGetTrapAddress(OSDISPATCH, ToolTrap) !=
  99.         NGetTrapAddress(UNIMPLEMENTED, ToolTrap))
  100.         top_mem = StripAddress(MFTopMem());
  101.     else
  102.         top_mem = StripAddress(TopMem());
  103.     
  104.     /*
  105.         Get QuickDraw globals, so we can find the screen size.
  106.     */
  107.     QD_globals = (QuickDraw *) ( *(Byte **) CurrentA5 -
  108.         (sizeof(QuickDraw) - sizeof(GrafPtr)) );
  109.  
  110.     /*
  111.         Create a window (centered) and set its font.
  112.     */
  113.     bounds.top = QD_globals->screenBits.bounds.top + GetMBarHeight() +
  114.         (QD_globals->screenBits.bounds.bottom -
  115.         QD_globals->screenBits.bounds.top - GetMBarHeight()
  116.         - BOX_HEIGHT) / 2;
  117.     bounds.bottom = bounds.top + BOX_HEIGHT;
  118.     bounds.left = QD_globals->screenBits.bounds.left +
  119.         (QD_globals->screenBits.bounds.right -
  120.         QD_globals->screenBits.bounds.left - BOX_WIDTH) / 2;
  121.     bounds.right = bounds.left + BOX_WIDTH;
  122.     my_window = NewWindow( nil, &bounds, "\pFKEY", true, dBoxProc,
  123.         (WindowPtr) MOVE_TO_FRONT, true, nil );
  124.     /*
  125.         It would seem reasonable to use a null string as the window
  126.         title and use false as the goAwayFlag parameter, since the
  127.         window has no title bar.  Then I noticed that the "Select
  128.         rear window" QuicKey (in QuicKeys 2.0.1) would send the
  129.         FKEY's window behind other windows, but would not bring it back.
  130.         Changing these parameters fixes this.
  131.     */
  132.     if (my_window == nil)
  133.     {
  134.         DEBUGSTR("\pResmap can't create window.");
  135.         goto getout;
  136.     }
  137.     ((WindowPeek)my_window)->windowKind = 1;
  138.     SetPort( my_window );
  139.     TextSize( 12 );
  140.     TextFont( geneva );
  141.     
  142.     /*
  143.         Frame the rectangle in which we'll display the scrolling list.
  144.     */
  145.     listbox = my_window->portRect;
  146.     InsetRect( &listbox, 3, 3 );
  147.     /* Leave room for the Cancel button */
  148.     listbox.bottom -= BUTTON_HEIGHT + 2*BUTTON_GAP;
  149.     FrameRect( &listbox );
  150.     
  151.     /*
  152.         Create the Cancel button.
  153.     */
  154.     SetRect( &button_rect,
  155.         (listbox.right + listbox.left - BUTTON_WIDTH) / 2,
  156.         listbox.bottom + BUTTON_GAP,
  157.         (listbox.right + listbox.left + BUTTON_WIDTH) / 2,
  158.         listbox.bottom + BUTTON_GAP + BUTTON_HEIGHT );
  159.     button = NewControl( my_window, &button_rect, "\pCancel", true,
  160.         0, 0, 1, pushButProc, nil );
  161.     if (button == nil)
  162.     {
  163.         DEBUGSTR("\pCouldn't create a button");
  164.         SetPort( save_port );
  165.         DisposeWindow( my_window );
  166.         goto getout;
  167.     }
  168.     
  169.     /* Create the list. */
  170.     listview = listbox;
  171.     InsetRect( &listview, 1, 1 );
  172.     listview.right -= 15;    /* Don't include the scroll bar. */
  173.     SetRect( &databounds, 0, 0, 1, 0 );    /* 1 column, │ 0 rows */
  174.     ncell.h = ncell.v = 0;
  175.     list = LNew( &listview,
  176.         &databounds,    /* Preallocated storage */
  177.         ncell,    /* Cell size: use default. */
  178.         0,        /* default LDEF */
  179.         my_window,
  180.         false,    /* Don't draw yet. */
  181.         false,    /* No grow box. */
  182.         false,    /* No horizontal scrolling. */
  183.         true     /* We do vertical scrolling. */
  184.         );
  185.     if (!Check_handle( (Handle) list, top_mem ))
  186.     {
  187.         DEBUGSTR("\pBad list handle!");
  188.         DisposeControl( button );
  189.         SetPort( save_port );
  190.         DisposeWindow( my_window );
  191.         goto getout;
  192.     }
  193.     
  194.     /* Fill the list. */
  195.     ncell.h = ncell.v =0;    /* ncell will always be in column 0 */
  196.     row_num = 0;
  197.     fcb.ioCompletion = nil;
  198.     fcb.ioFCBIndx = nil;
  199.     this_map = (ResMap_h) TopMapHndl;
  200.     while ( Check_handle( (Handle) this_map, top_mem ) )
  201.     {
  202.         ncell.v = row_num;
  203.         (void) LAddRow( 1, row_num, list );
  204.         fcb.ioRefNum = (**this_map).refnum;
  205.         fcb.ioVRefNum = 0;
  206.         fcb.ioNamePtr = (StringPtr) filename;
  207.         PBGetFCBInfo( &fcb, false );
  208.         if ( fcb.ioResult == noErr )
  209.             LSetCell( &filename[1], (int) filename[0], ncell, list );
  210.         else
  211.             LSetCell( "***** Can't get file info *****", 31, ncell, list );
  212.         if ( (**this_map).refnum == cur_resfile )
  213.             LSetSelect( true, ncell, list );
  214.         this_map = (**this_map).next;
  215.         ++row_num;
  216.     }
  217.     ncell.v = row_num;
  218.     (void) LAddRow( 6, ncell.v, list );
  219.     LSetCell( "-------------------------------", 31, ncell, list );
  220.     ++ncell.v;
  221.     LSetCell( "This FKEY shows the list of", 27, ncell, list );
  222.     ++ncell.v;
  223.     LSetCell( "resource maps. The CurResFile", 29, ncell, list );
  224.     ++ncell.v;
  225.     LSetCell( "is highlighted.  Vers. 1.3.", 27, ncell, list );
  226.     ++ncell.v;
  227.     LSetCell( "Freeware by Jim Walker, 1991.", 29, ncell, list );
  228.     ++ncell.v;
  229.     LSetCell( "76367.2271@compuserve.com", 25, ncell, list );
  230.     
  231.     LDoDraw( true, list );
  232.     
  233.     /*
  234.         Process update, mousedown, and keydown events.  Quit when we
  235.         see a click on the Cancel button, or any keydown.
  236.     */
  237.     done = false;
  238.     while (!done)
  239.     {
  240.         (void)GetNextEvent( everyEvent, &event );
  241.         SetPort( my_window );    /* Probably not needed. */
  242.         switch (event.what)
  243.         {
  244.             case mouseDown:
  245.                 place = FindWindow( event.where, &which_window );
  246.                 if ( (which_window == my_window) && (place == inContent) )
  247.                 {
  248.                     GlobalToLocal( &event.where );
  249.                     part = FindControl( event.where, my_window,
  250.                         &which_control );
  251.                     if (which_control == button)
  252.                     {
  253.                         part = TrackControl( button, event.where, nil );
  254.                         if (part == inButton)
  255.                             done = true;
  256.                     }
  257.                     else if (which_control != nil) /* scroll bar */
  258.                         LClick( event.where, event.modifiers, list );
  259.                 }
  260.                 else
  261.                     SysBeep(1);
  262.                 break;
  263.             case updateEvt:
  264.                 if ((WindowPtr)event.message == my_window)
  265.                 {
  266.                     BeginUpdate( my_window );
  267.                         LUpdate( my_window->visRgn, list );
  268.                         FrameRect( &listbox );
  269.                         DrawControls( my_window );
  270.                     EndUpdate( my_window );
  271.                 }
  272.                 break;
  273.             case keyDown:
  274.                 done = true;
  275.                 break;
  276.         }
  277.     }
  278.  
  279.     LDispose( list );
  280.     DisposeControl( button );
  281.     SetPort( save_port );
  282.     DisposeWindow( my_window );
  283.  
  284. getout:
  285.     running = false;
  286. reentrant_exit:
  287.     asm {
  288.         movem.l    (SP)+, a0-a5/d0-d7
  289.     }
  290. }
  291.  
  292.  
  293. /* --------------------------- Check_handle --------------------------- */
  294. Boolean        Check_handle( Handle h, Ptr top_mem )
  295. {
  296.     THz        zone;
  297.     
  298.     if (h == nil)
  299.         return( false );
  300.     
  301.     if ((long)h & 1L)
  302.     {
  303.         DEBUGSTR("\pOdd handle");
  304.         return( false );
  305.     }
  306.     
  307.  
  308.     if (StripAddress((Ptr)h) > top_mem)
  309.     {
  310.         DEBUGSTR("\pHigh handle");
  311.         return( false );
  312.     }
  313.     
  314.     if (*h == nil)
  315.     {
  316.         DEBUGSTR("\pEmpty handle");
  317.         return( false );
  318.     }
  319.     
  320.     if (StripAddress((Ptr)*h) > top_mem)
  321.     {
  322.         DEBUGSTR("\pHigh master pointer");
  323.         return( false );
  324.     }
  325.     
  326.     if ((long)*h & 1L)
  327.     {
  328.         DEBUGSTR("\pOdd master pointer");
  329.         return( false );
  330.     }
  331.     
  332.     zone = HandleZone( h );
  333.     if (MemError() != noErr)
  334.     {
  335.         DEBUGSTR("\pAttempt to operate on a free block?");
  336.         return( false );
  337.     }
  338.     
  339.     return( true );
  340. }